<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8"/>
    <meta content="IE=Edge" name="viewport"/>
    <title>ESP32发动机信号发生器</title>
    <link href="https://www.w3school.com.cn/lib/bs/bootstrap.css" rel="stylesheet"/>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet"/>

    <style>
        .bd-placeholder-img {
            font-size: 1.125rem;
            text-anchor: middle;
            -webkit-user-select: none;
            -moz-user-select: none;
            user-select: none;
        }

        @media (min-width: 768px) {
            .bd-placeholder-img-lg {
                font-size: 3.5rem;
            }
        }
    </style>
</head>

<body>
<div class="container mt-3">
    <ul class="nav nav-tabs" id="myTab" role="tablist">
        <a class="d-flex align-items-center mb-3 ms-3 mb-md-0 me-md-auto text-dark text-decoration-none">
            <svg class="bi bi-cc-square" fill="red" height="32" viewBox="0 0 16 16" width="32"
                 xmlns="http://www.w3.org/2000/svg">
                <path d="M15 2a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1zM0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm5.408 3.89c-.83 0-1.318.64-1.318 1.753v.742c0 1.108.479 1.727 1.318 1.727.69 0 1.138-.435 1.187-1.05h1.147v.114c-.058 1.147-1.029 1.938-2.343 1.938-1.612 0-2.518-1.028-2.518-2.729v-.747c0-1.7.914-2.75 2.518-2.75 1.319 0 2.29.812 2.343 1.999v.11H6.595c-.049-.638-.506-1.108-1.187-1.108Zm5.404 0c-.831 0-1.319.64-1.319 1.753v.742c0 1.108.48 1.727 1.319 1.727.69 0 1.138-.435 1.186-1.05h1.147v.114c-.057 1.147-1.028 1.938-2.342 1.938-1.613 0-2.518-1.028-2.518-2.729v-.747c0-1.7.914-2.75 2.518-2.75 1.318 0 2.29.812 2.342 1.999v.11h-1.147c-.048-.638-.505-1.108-1.186-1.108Z"
                      fill-rule="evenodd"/>
                <path d="M15 2a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1zM0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm5.408 3.89c-.83 0-1.318.64-1.318 1.753v.742c0 1.108.479 1.727 1.318 1.727.69 0 1.138-.435 1.187-1.05h1.147v.114c-.058 1.147-1.029 1.938-2.343 1.938-1.612 0-2.518-1.028-2.518-2.729v-.747c0-1.7.914-2.75 2.518-2.75 1.319 0 2.29.812 2.343 1.999v.11H6.595c-.049-.638-.506-1.108-1.187-1.108Zm5.404 0c-.831 0-1.319.64-1.319 1.753v.742c0 1.108.48 1.727 1.319 1.727.69 0 1.138-.435 1.186-1.05h1.147v.114c-.057 1.147-1.028 1.938-2.342 1.938-1.613 0-2.518-1.028-2.518-2.729v-.747c0-1.7.914-2.75 2.518-2.75 1.318 0 2.29.812 2.342 1.999v.11h-1.147c-.048-.638-.505-1.108-1.186-1.108Z"
                      fill-rule="evenodd"/>
            </svg>
            <span class="fs-4 ms-3 ">EGCC</span>
        </a>
        <li class="nav-item" role="presentation">
            <button class="nav-link active" data-bs-target="#setting-tab-pane" data-bs-toggle="tab" id="setting-tab"
                    role="tab" type="button">
                <i class="bi bi-gear me-2"></i>设置
            </button>
        </li>
        <li class="nav-item" role="presentation">
            <button class="nav-link" data-bs-target="#cc-tab-pane" data-bs-toggle="tab" id="cc-tab" role="tab"
                    type="button">
                <i class="bi bi-yelp me-2"></i>相位
            </button>
        </li>
        <li class="nav-item" role="presentation">
            <button class="nav-link" data-bs-target="#help-tab-pane" data-bs-toggle="tab" id="help-tab" role="tab"
                    type="button">
                <i class="bi bi-patch-question me-2"></i>帮助
            </button>
        </li>
    </ul>
    <div class="tab-content" id="myTabContent">
        <div aria-labelledby="home-tab" class="tab-pane fade show active" id="setting-tab-pane" role="tabpanel"
             tabindex="0">
            <div class="container mt-3">
                <section class="jumbotron text-center">
                    <div class="container">
                        <h3 class="jumbotron-heading">基于ESP32的曲轴凸轮信号发生器</h3>
                        <p class="lead text-muted">
                            该方案采用乐鑫公司的ESP32芯片，可以产生1路360°可任意编辑的凸轮方波信号、1路360°可任意编辑的曲轴方波信号、2路0~3.3V的电压输出。网页通过websocket协议与ESP32通讯，协议为自定义。
                            <br>ESP32运行websocket server，IP地址需要局域网内使用mDNS服务进行服务发现，默认端口号80；网页运行client。</p>
                    </div>
                </section>
                <div class="input-group flex-nowrap">
                    <span class="input-group-text" id="addon-wrapping">URL</span>
                    <input class="form-control" id="ws-url" placeholder="ws://192.168.3.1:80/ws"
                           type="text" value="ws://192.168.3.1:80/ws">
                    <button class="btn btn-outline-secondary" id="btn-connect" type="button">连接</button>
                    <button class="btn btn-outline-secondary" data-bs-placement="top" data-bs-toggle="tooltip"
                            id="btn-close"
                            title="在突然与Server失去联系后，close完全关闭需要10秒以上的时间，该为系统API限制。" type="button"
                    >断开
                    </button>
                </div>
                <div class="row align-items-center  justify-content-center mt-3">
                    <div class="col col-4">
                        <div class="input-group flex-nowrap">
                            <span class="input-group-text">WIFI名称</span>
                            <input class="form-control" id="wifi-ssid" placeholder="esp32" type="text" value="esp32">
                            <button class="btn btn-outline-secondary" id="btn-set-ssid" type="button">设置</button>
                        </div>
                    </div>
                    <div class="col col-4">
                        <div class="input-group flex-nowrap">
                            <span class="input-group-text">WIFI密码</span>
                            <input class="form-control" id="wifi-passeord" placeholder="12345678"
                                   type="text" value="12345678">
                            <button class="btn btn-outline-secondary" id="btn-set-password" type="button">设置</button>
                        </div>
                    </div>
                    <div class="col col-4">
                        <div class="input-group flex-nowrap  justify-content-end ">
                            <span class="input-group-text">芯片重置</span>
                            <button class="btn btn-outline-secondary" id="btn-reset-nvs" type="button">重置
                            </button>
                        </div>
                    </div>
                </div>
                <div class="alert alert-light mt-3 ps-0 pe-0 align-items-end" role="alert">
                    <h4 class="alert-heading">Some Information</h4>
                    <div class="progress mb-2" style="height: 5px;">
                        <div class="progress-bar progress-bar-striped progress-bar-animated" id="connect-progress"
                             role="progressbar" style="width:0%"></div>
                    </div>
                    <textarea class="form-control" id="tip-textarea" rows="16"></textarea>
                </div>
            </div>
        </div>
        <div class="tab-pane fade" id="cc-tab-pane" role="tabpanel" tabindex="0">
            <div class="mb-3">
                <div class="pre-scrollable" style="height: 240px; overflow-x: scroll; overscroll-behavior: contain">
                    <div id="signal-chart" style="width: 7000px; height: 220px"></div>
                </div>
            </div>
            <div class="d-flex  flex-row bd-highlight justify-content-around align-items-center">
                <button class="btn btn-outline-secondary" id="btn-update-cas" type="button">更新凸轮波形</button>
                <button class="btn btn-outline-secondary" id="btn-update-crs" type="button">更新曲轴波形</button>
                <button class="btn btn-outline-secondary" id="btn-write-cas" type="button">写入凸轮波形</button>
                <button class="btn btn-outline-secondary" id="btn-write-crs" type="button">写入曲轴波形</button>
            </div>
            <hr class="divider border-2  text-warning">
            <div class="row align-items-center">
                <div class="col">
                    <div class="input-group mb-3" data-bs-toggle="tooltip">
                        <span class="input-group-text">电压输出通道 0</span>
                        <input class="form-control" data-bs-placement="top" id="dac0-val" title="0~3300mv" type="number"
                               value="0" onchange="value=value>3300?3300:value;value=value<0?0:value;">
                        <span class="input-group-text">mv</span>
                        <button class="btn btn-outline-secondary" id="btn-set-dac0" type="button">输出</button>
                    </div>

                </div>
                <div class="col">
                    <div class="input-group mb-3">
                        <span class="input-group-text">电压输出通道 1</span>
                        <input class="form-control" data-bs-placement="top" id="dac1-val" title="0~3300mv" type="number"
                               value="0" onchange="value=value>3300?3300:value;value=value<0?0:value;">
                        <span class="input-group-text">mv</span>
                        <button class="btn btn-outline-secondary" id="btn-set-dac1" type="button">输出</button>
                    </div>
                </div>
            </div>
            <div>
                <div class="row align-items-center">
                    <div class="col">
                        <div class="input-group mb-3">
                            <span class="input-group-text">转速允许最大值</span>
                            <input class="form-control" id="speed-max"
                                   onchange=" value=value>20000?20000:value;document.getElementById('speedSlider').max=value"
                                   type="number" value="15000">
                            <span class="input-group-text">rpm</span>
                        </div>
                    </div>
                    <div class="col">
                        <div class="input-group mb-3">
                            <span class="input-group-text">发动机转速</span>
                            <input class="form-control" id="speed-target" type="number" value="0">
                            <span class="input-group-text">rpm</span>
                            <button class="btn btn-outline-secondary" id="btn-confirm" type="button">发送</button>
                        </div>
                    </div>

                </div>
                <div class="row align-items-center">
                    <div class="col">
                        <div class="input-group mb-3">
                            <span class="input-group-text">转速允许最小值</span>
                            <input class="form-control" id="speed-min"
                                   onchange="value=value<0?0:value;document.getElementById('speedSlider').min=value"
                                   type="number" value="0">
                            <span class="input-group-text">rpm</span>

                        </div>
                    </div>
                    <div class="col">
                        <div class="input-group mb-3">
                            <input class="form-range" id="speedSlider" max="15000" min="0"  step="1" type="range" value="0"/>
                        </div>
                    </div>
                </div>
            </div>
            <div class="alert alert-warning" id="mes-alert" role="alert">
            </div>
        </div>
        <div class="tab-pane fade" id="help-tab-pane" role="tabpanel" tabindex="0">
            <div class="container mt-2">
                <h5 class="jumbotron-heading">EGCC介绍</h5>
                <p class="lead text-muted"><span>该方案采用乐鑫公司的ESP32芯片制作，方案采用定时器+GPIO操作，简单方便，无需过多硬件需求。芯片采用GPIO18作为凸轮信号输出针脚，采用GPIO17作为曲轴信号输出针脚，采用GPIO25作为电压输出通道0，采用GPIO26作为电压输出通道1。usb采用串口烧录和debug调试信息输出和芯片的供电。</span>
                </p><h5 id='通讯方案'><span>通讯方案</span></h5>
                <p>
                <p class="lead text-muted">
                    <span class="lead text-muted">通讯方案采用websocket协议。esp32芯片作为websocket服务器，上位机网页作为websocket客户端，两者采用局域网内通讯。websocket的URL地址格式为：ws://</span><strong><span>192.168.0.1</span></strong><span>:80:/ws 。服务器端口号固定80。上位机可以采用串口获取esp32芯片的server服务器IP地址，或者在PC端中使用mDNS服务进行局域网服务器搜索（如window10可在命令行CMD.exe中输入指令：ping egcc -4 ，即可得到esp32的websocket服务器IP地址）。得到ESP32 Sever 的IP地址后，替换格式中ws://</span><strong><span>192.168.0.1</span></strong><span>:80:/ws中的IP地址，输入网页URL地址中，即可连接。</span>
                </p>
                </p><h5 id='通讯协议'><span>通讯协议</span></h5>
                <p class="lead text-muted"><span>协议很简单，websocket一帧只能传输一条指令，多的esp32将忽略。</span></p>
                <p class="lead text-muted"><span>协议以字符</span><strong><span>##</span></strong><span>+指令代号开头，为ASCII字符，指令代号从字符</span><strong><span>”A“</span></strong><span>开始：</span>
                </p>
                <ol class="lead text-muted">
                    <li><span>##AXXXX。设置esp32输出转速，其中XXXX为16进制字符。</span></li>
                    <li><span>##BXXXX。</span></li>
                </ol>
            </div>
        </div>
    </div>
</div>
</div>

<script src="https://cdn.bootcdn.net/ajax/libs/bootstrap-slider/11.0.2/bootstrap-slider.js"></script>
<script src="https://cdn.staticfile.org/echarts/5.4.3/echarts.min.js"></script>
<script src="https://www.w3school.com.cn/lib/bs/bootstrap.js"></script>

<script src="index.js"></script>
</body>
</html>
